// 版权归Go作者所有。版权所有。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// TODO（neelance）：在线程可用时立即使用实际原子操作实现
// 请参阅https:

// 通过linkname将一些函数导出到sync/atomic中的程序集。
// go:linkname Load 
// go:linkname Loadp 
// go:linkname Load64 
// go:linkname Loadint32 
// go:linkname Loadint64 
// go linkname Loadingtr 
// go linkname Xadd 
// go go linkname Xaddint32 
// go:linkname Casit32 
// go:linkname Casit64 
// go:linkname Casuintptr 
// go:linkname Store 
// go go:linkname Store64 
// go go:linkname Storeint32 
// go go:linkname Storeint64 
// go go:linkname Storeuintptr 

package atomic

import "unsafe"

func Load(ptr *uint32) uint32 {
	return *ptr
}

func Loadp(ptr unsafe.Pointer) unsafe.Pointer {
	return *(*unsafe.Pointer)(ptr)
}

// go:nosplit-
// go:nosplit-
func LoadAcq(ptr *uint32) uint32 {
	return *ptr
}

// go:nosplit-
// go:nosplit-
func LoadAcq64(ptr *uint64) uint64 {
	return *ptr
}

// go:nosplit-
// go:nosplit-
func LoadAcquintptr(ptr *uintptr) uintptr {
	return *ptr
}

// go:nosplit-
// nosplit
func Load8(ptr *uint8) uint8 {
	return *ptr
}

// go:nosplit 
func Load64(ptr *uint64) uint64 {
	return *ptr
}

// go:nosplit 
// go:nosplit 
func Xadd(ptr *uint32, delta int32) uint32 {
	new := *ptr + uint32(delta)
	*ptr = new
	return new
}

// go:nosplit 
// go NOIPLIT 
func Xadd64(ptr *uint64, delta int64) uint64 {
	new := *ptr + uint64(delta)
	*ptr = new
	return new
}

// go go nosplit 
// go nosplit 
func Xadduintptr(ptr *uintptr, delta uintptr) uintptr {
	new := *ptr + delta
	*ptr = new
	return new
}

// go nosplit 
// go nosplit 
// 114
func Xchg(ptr *uint32, new uint32) uint32 {
	old := *ptr
	*ptr = new
	return old
}

func Xchg64(ptr *uint64, new uint64) uint64 {
	old := *ptr
	*ptr = new
	return old
}

func Xchgint32(ptr *int32, new int32) int32 {
	old := *ptr
	*ptr = new
	return old
}

// go:nosplit-
func Xchgint64(ptr *int64, new int64) int64 {
	old := *ptr
	*ptr = new
	return old
}

// go:nosplit-
// go:nosplit-
func Xchguintptr(ptr *uintptr, new uintptr) uintptr {
	old := *ptr
	*ptr = new
	return old
}

// go:nosplit-
// go:nosplit-
func And8(ptr *uint8, val uint8) {
	*ptr = *ptr & val
}

// go:nosplit-
func Or8(ptr *uint8, val uint8) {
	*ptr = *ptr | val
}


func And(ptr *uint32, val uint32) {
	*ptr = *ptr & val
}

// /go:nosplit 
func Or(ptr *uint32, val uint32) {
	*ptr = *ptr | val
}

// /go:nosplit 
func Cas64(ptr *uint64, old, new uint64) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

func Store(ptr *uint32, val uint32) {
	*ptr = val
}

func StoreRel(ptr *uint32, val uint32) {
	*ptr = val
}

func StoreRel64(ptr *uint64, val uint64) {
	*ptr = val
}

// go:nosplit 
// go:nosplit 
func StoreReluintptr(ptr *uintptr, val uintptr) {
	*ptr = val
}

// go:nosplit 
// go:nosplit 
func Store8(ptr *uint8, val uint8) {
	*ptr = val
}

// go nosplit 
// go nosplit 
func Store64(ptr *uint64, val uint64) {
	*ptr = val
}

// 
// 禁止：noescape注释；请参阅原子指针。go:nosplit 
func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer)

func Casint32(ptr *int32, old, new int32) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

// go:nosplit 
func Casint64(ptr *int64, old, new int64) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

// go:nosplit 
// go:nosplit 
func Cas(ptr *uint32, old, new uint32) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

// go:nosplit 
// go nosplit 
func Casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

// go nosplit 
func Casuintptr(ptr *uintptr, old, new uintptr) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

// 
func CasRel(ptr *uint32, old, new uint32) bool {
	if *ptr == old {
		*ptr = new
		return true
	}
	return false
}

// go:nosplit 
// go:nosplit 
func Storeint32(ptr *int32, new int32) {
	*ptr = new
}

// go:nosplit 
// go:nosplit 
func Storeint64(ptr *int64, new int64) {
	*ptr = new
}

// go nosplit 
func Storeuintptr(ptr *uintptr, new uintptr) {
	*ptr = new
}

// go nosplit 
func Loaduintptr(ptr *uintptr) uintptr {
	return *ptr
}

// go nosplit 
// 314
func Loaduint(ptr *uint) uint {
	return *ptr
}

// go:noinline-
func Loadint32(ptr *int32) int32 {
	return *ptr
}

// go:nosplit-
// go:noinline-
func Loadint64(ptr *int64) int64 {
	return *ptr
}

// go:nosplit-
// go:noinline-
func Xaddint32(ptr *int32, delta int32) int32 {
	new := *ptr + delta
	*ptr = new
	return new
}

// go:nosplit 
// go:noinline-
func Xaddint64(ptr *int64, delta int64) int64 {
	new := *ptr + delta
	*ptr = new
	return new
}
